#include "DdapData.h"

#include <bits/types/FILE.h>
#include <bits/types/struct_timeval.h>
#include <bits/types/struct_tm.h>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fcntl.h>  //这个头文件提供了对文件描述符的控制
/*
    这个头文件中定义的函数主要包括：

fcntl：用于操作文件描述符的各种属性，如设置非阻塞模式、获取/设置文件锁等。
open：用于打开或创建文件，并返回一个文件描述符。
*/
#include "Channel.h"
#include "CurrentThread.h"
#include "DDAP.pb.h"
#include "ECCOper.h"
#include "Logging.h"
#include "Timer.h"
#include "utils.h"

#include <functional>
#include <iomanip>
#include <iostream>
#include <memory>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <pthread.h>
#include <sched.h>
#include <sstream>
#include <string>
#include <string_view>
#include <sys/epoll.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <vector>

using namespace monsoon;

namespace droneswarm
{
    // MimeType类只会初始化一次，初始化可以使用pthread_once方法来进行
    // pthread_once_t是POSIX线程库中的一个数据类型，通常用于一次性初始化。
    //它通常与pthread_once函数一起使用，确保某个初始化函数在多线程环境中只被执行一次。
    // pthread_once_t MimeType::once_control = PTHREAD_ONCE_INIT;

    const __uint32_t DEFALUT_EVENT = EPOLLIN | EPOLLET | EPOLLONESHOT;
    const int DEFALULT_EXPIRED_TIME = 2000;            // ms
    const int DEFAULT_KEEP_ALIVE_TIME = 5 * 6 * 1000;  // ms

    // std::unordered_map< std::string, std::string > MimeType::mime;

    // std::string weekdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    // std::string months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

    // void MimeType::init()
    // {
    //     mime[ ".html" ] = "text/html";
    //     mime[ ".avi" ] = "video/x-msvideo";
    //     mime[ ".bmp" ] = "image/bmp";
    //     mime[ ".c" ] = "text/plain";
    //     mime[ ".doc" ] = "application/msword";
    //     mime[ ".gif" ] = "image/gif";
    //     mime[ ".gz" ] = "application/x-gzip";
    //     mime[ ".htm" ] = "text/html";
    //     mime[ ".ico" ] = "image/x-icon";
    //     mime[ ".jpg" ] = "image/jpeg";
    //     mime[ ".png" ] = "image/png";
    //     mime[ ".txt" ] = "text/plain";
    //     mime[ ".log" ] = "text/plain";
    //     mime[ ".mp3" ] = "audio/mp3";
    //     mime[ ".json" ] = "application/json";
    //     mime[ "default" ] = "text/html";
    // }

    // std::string MimeType::getMime( const std::string &suffix )
    // {
    //     pthread_once( &once_control, MimeType::init );
    //     if ( mime.find( suffix ) == mime.end() )
    //         return mime[ "default" ];
    //     else
    //         return mime[ suffix ];
    // }

    DdapData::DdapData( EventLoop *loop, int connfd, unsigned char symmetricKey[ 32 ] )
        : loop_( loop )
        , channel_( new Channel( loop, connfd ) )
        , fd_( connfd )
        , error_( false )
        , connectionState_( H_CONNECTED )
        , nowReadPos_( 0 )
        , state_( STATE_PARSE_NEEDHMACMESSAGE )
        , keepAlive_( false )
        , isExistHeader( true )
    {
        channel_->setReadHandler( std::bind( &DdapData::handleRead, this ) );
        channel_->setWriteHandler( std::bind( &DdapData::handleWrite, this ) );
        channel_->setConnHandler( std::bind( &DdapData::handleConn, this ) );
        memcpy( symmetricKey_, symmetricKey, 32 );
        // std::string symm_str = base64_encode( symmetricKey_, 32 );
        // std::cout << symm_str << std::endl;
    }

    DdapData::~DdapData()
    {
        std::cout << "连接" << fd_ << "已断开" << std::endl;
        close( fd_ );
    }

    void DdapData::reset()
    {
        nowReadPos_ = 0;
        state_ = STATE_PARSE_NEEDHMACMESSAGE;
        if ( timer_.lock() )
        {
            std::shared_ptr< TimerNode > my_timer( timer_.lock() );
            my_timer
                ->clearReq();  //这个代码是调用TimerNode的clearReq方法，清除掉TimerNode所持有的指向HttpData的智能指针。
            timer_.reset();  //最后清楚本类中对TimerNode的引用
            //在TimerManager::handleExpiredEvent方法中也会清除掉对TimerNode的引用，这个清除之后，没有智能指针指向TimerNode
            // TimerNode就会执行析构函数
        }
    }

    void DdapData::handleRead()
    {
        __uint32_t &events_ = channel_->getEvents();
        // std::cout << "156" << std::endl;
        do
        {
            // std::cout << "159" << std::endl;
            bool zero = false;
            int read_num = readn( fd_, inBuffer_, zero );

            //   unsigned char inBuffer[ 4096 ];
            //   int num = read( fd_, inBuffer, 4096 - 1 );
            //   std::cout << "167::" << read_num << std::endl;
            //  std::cout << inBuffer_ << std::endl;
            //   inBuffer_.clear();
            if ( read_num > 0 )
            {
                std::cout << "读取数据成功，数据大小为：" << read_num << std::endl;
                LOG << "Request:" << inBuffer_ << '\n';
            }

            if ( connectionState_ == H_DISCONNECTING )
            {
                //说明正在关闭连接，清楚数据
                inBuffer_.clear();
                break;
            }

            if ( read_num < 0 )
            {
                perror( "Read Error!" );
                LOG << strerror( errno ) << '\n';
                error_ = true;
                handleError( fd_, 400, "Bad Read!" );
                break;
            }
            else if ( zero )
            {  // zero为true说明没有读取到数据
                // 有请求出现但是读不到数据，可能是Request
                // Aborted，或者来自网络的数据没有达到等原因
                // 最可能是对端已经关闭了，统一按照对端已经关闭处理
                // error_ = true;
                connectionState_ = H_DISCONNECTING;
                if ( read_num == 0 )
                {
                    break;
                }
            }

            if ( state_ == STATE_PARSE_NEEDHMACMESSAGE )
            {
                NEEDHMACMESSAGEState flag = this->parseNeedHmacMessage();

                if ( flag == PARSE_NEEDHMACMESSAGE_AGAIN )
                {
                    break;
                }
                else if ( flag == PARSE_NEEDHMACMESSAGE_ERROR )
                {
                    perror( "PARSE_NEEDHMACMESSAGE_ERROR" );
                    LOG << "FD = " << fd_ << "," << inBuffer_ << "******" << '\n';
                    inBuffer_.clear();
                    error_ = true;
                    handleError( fd_, 401, "Bad NeedHmacMessage!" );
                    break;
                }
                else
                {  //进入到这里说明NEEDHMACMESSAGE解析成功。接下来就是处理加密的消息了
                    state_ = STATE_PARSE_ENCRYPTMESSAGE;
                    // std::cout << "进入 STATE_PARSE_ENCRYPTMESSAGE " << std::endl;
                    LOG << "PARSE_NEEDHMACMESSAGE_SUCESS\n";
                }

                //到了解析ENCRYPTMESSAGE阶段
                if ( state_ == STATE_PARSE_ENCRYPTMESSAGE )
                {
                    ENCRYPTMESSAGEState flag = this->parseEncryptMessage();
                    if ( flag == PARSE_ENCRYPTMESSAGE_ERROR )
                    {
                        perror( "PARSE_ENCYPTMESSAGE_ERROR" );
                        error_ = true;
                        handleError( fd_, 402, "Bad EncryptMessage" );
                        break;
                    }
                    else
                    {  //这里就是ENCRYPTMESSAGEState解析成功，然后就是处理STATE_PARSE_FULLMESSAGE阶段了
                        state_ = STATE_PARSE_FULLMESSAGE;
                        // std::cout << "进入 STATE_PARSE_FULLMESSAGE " << std::endl;
                        LOG << "PARSE_ENCRYPTMESSAGE_SUCESS\n";
                    }

                    //判断请求方法
                }

                if ( state_ == STATE_PARSE_FULLMESSAGE )
                {

                    FULLMESSAGEState flag = this->parseFullMessage();

                    if ( flag == PARSE_FULLMESSAGE_ERROR )
                    {
                        perror( "PARSE_FULLMESSAGE_ERROR" );
                        error_ = true;
                        handleError( fd_, 403, "Bad Fullmessage" );
                    }
                    else
                    {
                        state_ = STATE_MESSAGEINFO_ANALYSIS;
                        // std::cout << "进入 STATE_MESSAGEINFO_ANALYSIS " << std::endl;
                        LOG << "PARSE_FULLMESSAGE_SUCESS\n";
                    }
                }
                //到这一阶段说明请求体也接收完毕
                if ( state_ == STATE_MESSAGEINFO_ANALYSIS )
                {

                    AnalysisState flag = this->analysisMessage();

                    if ( flag == ANALYSIS_SUCCESS )
                    {
                        //如果分析成功，则阶段结束
                        state_ = STATE_MESSAGE_FINSH;
                        // std::cout << "STATE_MESSAGE_FINSH" << std::endl;
                        break;
                    }
                    else
                    {  //否则，消息不是按照标准格式来定义的，是错误的。
                        error_ = true;
                        handleError( fd_, 405, "解析错误" );
                        break;
                    }
                }
            }

        } while ( false );

        //如果没有错误，error_为false时会进入。
        if ( !error_ )
        {
            //如果error_是false的，
            if ( outBuffer_.size() > 0 )
            {
                handleWrite();
            }
            if ( !error_ && state_ == STATE_MESSAGE_FINSH )
            {
                //如果没有错误且状态为处理完成，则重置对象数据。
                this->reset();
                //如果还有数据，并且连接状态不为正在断开，则递归调用handleRead()继续处理剩余的数据。
                // inBuffer_还有数据说明接收的还有部分不完整的数据流。，需要继续接收
                if ( inBuffer_.size() > 0 )
                {
                    if ( connectionState_ != H_DISCONNECTING )
                    {
                        // std::cout << "318" << std::endl;
                        handleRead();
                    }
                }
            }
            else if ( !error_ && connectionState_ != H_DISCONNECTED )
            {
                events_ |= EPOLLIN;
            }
        }
    }

    void DdapData::handleWrite()
    {
        //如果错误标志位为false，且连接状态不是关闭的。则可以写数据
        if ( !error_ && connectionState_ != H_DISCONNECTED )
        {
            __uint32_t &events_ = channel_->getEvents();
            //写数据
            int writeNum = writen( fd_, outBuffer_ );
            std::cout << "发送数据成功，数据大小为：" << writeNum << std::endl;
            if ( writeNum < 0 )
            {
                //则说明写入数据失败
                perror( "Write Error!" );
                LOG << "Write Error!\n";
                error_ = true;
                events_ = 0;
                //如果写入数据失败，会将events_ =
                // 0置为0，并且如果没有数据可写，那么会一直为0，后续的执行handleConn函数中 写入失败时， error_ =
                // true了，在handleConn函数中就无法进入if和else if 只会进入else，来进行关闭操作。
            }
            // std::cout << "数据发送成功，发送的数据大小：" << writeNum << std::endl;
            //如果是有数据要写入的
            if ( outBuffer_.size() > 0 )
            {
                events_ |= EPOLLOUT;
            }
        }
    }

    void DdapData::seperateTimer()
    {
        // cout << "seperateTimer" << endl;
        if ( timer_.lock() )
        {
            std::shared_ptr< TimerNode > my_timer( timer_.lock() );
            my_timer->clearReq();
            timer_.reset();
        }
    }
    void DdapData::handleConn()
    {
        // std::cout << "handleConn" << std::endl;
        seperateTimer();  //将计时器清空。包括时间和指向本类的对象的智能指针，因为这个函数可能会处理关闭的事宜，因此就需要
        //先将计时器清空，如果
        __uint32_t &events_ = channel_->getEvents();
        //这里是获取events_的引用，即使将其设置为0了后面调用HandleConn后还是会设置为想要监听的事件
        //如果没有出错且连接已经建立了的
        if ( !error_ && connectionState_ == H_CONNECTED )
        {

            if ( events_ != 0 )
            {  //如果没有发生错误，且H_CONNECTED，那么这里是一定会进去的。因为未发生错误时，events_都会被重新设置。
                int timeout = DEFALULT_EXPIRED_TIME;
                if ( keepAlive_ )
                {
                    timeout = DEFAULT_KEEP_ALIVE_TIME;
                }
                if ( ( events_ & EPOLLIN ) && ( events_ & EPOLLOUT ) )
                {  //如果读写事件都存在,只设置优先级更高的写事件
                    events_ = __uint32_t( 0 );
                    events_ |= EPOLLOUT;
                }
                events_ |= EPOLLET;
                loop_->updatePoller( channel_, timeout );
            }  //如果events_=0并且连接仍然是保持的，则重置events_，并重置超时计时器
            else if ( keepAlive_ )
            {
                //如果为events_为空，但是对端还是想保持连接，就会更新epoll，重新设置定时器
                events_ |= ( EPOLLIN | EPOLLET );
                //重置超时计时器
                int timeout = DEFAULT_KEEP_ALIVE_TIME;
                loop_->updatePoller( channel_, timeout );
            }
            else
            {
                //这个情况就是event_ =0 且keepAlive_为false，说明这个连接可能已经关闭了，设置
                // DEFAULT_KEEP_ALIVE_TIME的一半来作为超时时间，如果超时时间到了都没有数据发送或接收，则关闭连接
                events_ |= ( EPOLLIN | EPOLLET );
                int timeout = ( DEFAULT_KEEP_ALIVE_TIME >> 1 );  //右移n位等于除以2^n。
                loop_->updatePoller( channel_, timeout );
            }
        }  //如果没有错误，但是连接正在关闭，并且需要发送数据时
        else if ( !error_ && connectionState_ == H_DISCONNECTING && ( events_ & EPOLLOUT ) )
        {
            events_ = ( EPOLLOUT | EPOLLET );
        }
        else
        {
            loop_->runInLoop( bind( &DdapData::handleClose, shared_from_this() ) );
        }
    }
    void DdapData::newEvent()
    {
        channel_->set_Events( DEFALUT_EVENT );
        loop_->addToPoller( channel_, DEFALULT_EXPIRED_TIME );
    }

    void DdapData::handleClose()
    {
        // std::cout << "3:DdapData::handleClose" << std::endl;
        connectionState_ = H_DISCONNECTED;
        std::shared_ptr< DdapData > guard( shared_from_this() );
        loop_->removeFromPoller( channel_ );
    }

    void DdapData::handleError( int fd, int err_num, std::string short_msg )
    {
        short_msg = " " + short_msg;
        char send_buff[ 4096 ];
        std::string body_buff, header_buff;
        // body_buff += "<html><title>哎~出错了</title>";
        // body_buff += "<body bgcolor=\"ffffff\">";
        // body_buff += std::to_string( err_num ) + short_msg;
        // body_buff += "<hr><em> LinYa's Web Server</em>\n</body></html>";

        header_buff += "HTTP/1.1 " + std::to_string( err_num ) + short_msg + "\r\n";
        header_buff += "Content-Type: text/html\r\n";
        header_buff += "Connection: Close\r\n";
        header_buff += "Content-Length: " + std::to_string( body_buff.size() ) + "\r\n";
        header_buff += "Server: sally-whq's Web Server\r\n";
        header_buff += "\r\n";
        // 错误处理不考虑writen不完的情况
        sprintf( send_buff, "%s", header_buff.c_str() );
        writen( fd, send_buff, strlen( send_buff ) );
        sprintf( send_buff, "%s", body_buff.c_str() );
        writen( fd, send_buff, strlen( send_buff ) );
    }
    NEEDHMACMESSAGEState DdapData::parseNeedHmacMessage()
    {                                  // std::cout << "385" << std::endl;
        std::string &str = inBuffer_;  //&引用，操作的是源数据。
        std::string cop = str;         //这是拷贝构造
        //首先进行数据的反序列化
        if ( !needHmacMsg_.ParseFromString( cop ) )
        {
            LOG << "NEEDHMACMESSAGE反序列化失败"
                << "\n";
            return PARSE_NEEDHMACMESSAGE_ERROR;
        }

        std::string_view EncryptMsgString = needHmacMsg_.encrptymessagestring();
        std::string_view hmacString = needHmacMsg_.hmacstring();

        size_t data_len = EncryptMsgString.size();
        unsigned char data[ data_len ];
        memcpy( data, EncryptMsgString.data(), data_len );
        unsigned char *compute_hmac_value = NULL;
        size_t hmac_value_len = 0;

        //自己计算hmac
        if ( !generateHmac( data, data_len, symmetricKey_, 32, &compute_hmac_value, &hmac_value_len ) )
        {
            std::cout << "从accept_fd: " << fd_ << "接收的数据，计算Hmac失败" << std::endl;
            LOG << "从accept_fd: " << fd_ << "接收的数据，计算Hmac失败"
                << "\n";
            return PARSE_NEEDHMACMESSAGE_ERROR;
        }

        size_t receive_hmac_len = hmacString.size();
        unsigned char receive_hmac[ receive_hmac_len ];
        memcpy( receive_hmac, hmacString.data(), receive_hmac_len );
        //首先判断长度是否一致

        if ( receive_hmac_len != hmac_value_len )
        {
            std::cout << "从accept_fd: " << fd_ << "接收的数据的Hmac和及计算的Hmac长度不一致，Hmac验证失败"
                      << std::endl;
            LOG << "从accept_fd: " << fd_ << "接收的数据的Hmac和及计算的Hmac长度不一致，Hmac验证失败"
                << "\n";
            OPENSSL_free( compute_hmac_value );
            return PARSE_NEEDHMACMESSAGE_ERROR;
        }

        //验证Hmac是否一致
        bool hmacVerityRet = verifyHmac( compute_hmac_value, receive_hmac, receive_hmac_len );
        if ( !hmacVerityRet )
        {
            std::cout << "从accept_fd: " << fd_ << "接收的数据的Hmac验证不通过" << std::endl;
            LOG << "从accept_fd: " << fd_ << "接收的数据的Hmac验证不通过"
                << "\n";
            OPENSSL_free( compute_hmac_value );
            return PARSE_NEEDHMACMESSAGE_ERROR;
        }
        // std::cout << "PARSE_NEEDHMACMESSAGE_SUCESS" << std::endl;
        OPENSSL_free( compute_hmac_value );
        return PARSE_NEEDHMACMESSAGE_SUCESS;
    }

    ENCRYPTMESSAGEState DdapData::parseEncryptMessage()
    {
        //获取EncryptMessage对象
        std::string EncryptMsgString = needHmacMsg_.encrptymessagestring();

        //反序列化
        if ( !encryptMsg_.ParseFromString( EncryptMsgString ) )
        {
            std::cout << "accept_fd: " << fd_ << "发送的EncrptyMessage对象反序列化失败" << std::endl;
            LOG << "accept_fd: " << fd_ << "发送的EncrptyMessage对象反序列化失败"
                << "\n";
            return PARSE_ENCRYPTMESSAGE_ERROR;
        }

        //序列化成功就是说明是正确的，接下来就是解密数据了
        //首先需要获得IV
        std::string iv_str = encryptMsg_.iv();
        // std::cout << iv_str.size() << std::endl;
        //获取加密的密文
        std::string cipherTextStr = encryptMsg_.encryptedfullmessagestring();

        size_t iv_len = iv_str.size();
        unsigned char iv[ iv_len ];
        memcpy( iv, iv_str.c_str(), iv_len );

        cipherTextLen_ = cipherTextStr.size();
        memcpy( cipherText_, cipherTextStr.c_str(), cipherTextLen_ );

        //解密数据
        symm_.setSymmeticKey( symmetricKey_ );
        symm_.setIv( iv );

        bool decryptRet = symm_.aes_Decryption( cipherText_, cipherTextLen_, plainText_, &plainTextLen_ );
        if ( !decryptRet )
        {
            std::cout << "accept_fd: " << fd_ << "发送的加密数据解密失败" << std::endl;
            LOG << "accept_fd: " << fd_ << "发送的加密数据解密失败失败"
                << "\n";
            return PARSE_ENCRYPTMESSAGE_ERROR;
        }
        // std::cout << "accept_fd: " << fd_ << "发送的加密数据解密成功" << std::endl;

        return PARSE_ENCRYPTMESSAGE_SUCESS;
    }
    FULLMESSAGEState DdapData::parseFullMessage()
    {  //获取FULLMESSAGE字符串
        std::string fullMsgStr( reinterpret_cast< const char * >( plainText_ ), plainTextLen_ );

        //将字符串进行反序列化
        if ( !fullMsg_.ParseFromString( fullMsgStr ) )
        {
            std::cout << "accept_fd: " << fd_ << "fullMsgStr反序列化失败" << std::endl;
            LOG << "accept_fd: " << fd_ << "fullMsgStr反序列化失败"
                << "\n";
            return PARSE_FULLMESSAGE_ERROR;
        }

        //这里就是序列化成功了然后就是分析对象
        if ( !parseMessage( fullMsg_, msgInfo_, fd_ ) )
        {
            std::cout << "accept_fd: " << fd_ << "FullMessage分析失败" << std::endl;
            LOG << "accept_fd: " << fd_ << "FullMessage分析失败"
                << "\n";
            return PARSE_FULLMESSAGE_ERROR;
        }

        //如果成功则说明结构是正确的，那么就进入下一阶段。
        return PARSE_FULLMESSAGE_SUCESS;
    }
    AnalysisState DdapData::analysisMessage()
    {
        MessageType mt = msgInfo_.mt;
        // std::string token = "123456";
        //创建管道
        if ( mt == DATA_REQUEST )
        {  //需要设置超时重传，以后再完善
            //数据请求消息是没有真实数据的。
            DataType dt = msgInfo_.dataType;

            if ( dt == BOTH )
            {
                std::string ds = "BOTH";
                // blockData.daop = droneswarm::DATAUPDATE;
                // std::string ds = "[0x123456789,DJI,master,legitimate]";
                std::string realData = getDataFromDispatch( ds );
                if ( realData.empty() )
                {
                    std::cerr << "ERROR: getDataFromDispatch " << std::endl;
                    return ANALYSIS_ERROR;
                }

                if ( !constructProtobufMessage( DATA_RESPONSE, realData, dt ) )
                {
                    std::cout << "constructProtobufMessage 错误" << std::endl;
                    return ANALYSIS_ERROR;
                }
                return ANALYSIS_SUCCESS;
            }
            else if ( dt == WHITELIST )
            {
                // int getDataRet = getBlockLegitimateData( realData );
                std::string ds = "legitimate";
                std::string realData = getDataFromDispatch( ds );

                // std::cout << realData << std::endl;
                if ( realData.empty() )
                {
                    std::cerr << "ERROR: getDataFromDispatch " << std::endl;
                    return ANALYSIS_ERROR;
                }

                if ( !constructProtobufMessage( DATA_RESPONSE, realData, dt ) )
                {
                    std::cout << "constructProtobufMessage 错误" << std::endl;
                    return ANALYSIS_ERROR;
                }
                return ANALYSIS_SUCCESS;
            }
            else if ( dt == BLACKLIST )
            {

                std::string ds = "illegal";
                std::string realData = getDataFromDispatch( ds );

                // std::cout << realData << std::endl;
                if ( realData.empty() )
                {
                    std::cerr << "ERROR: getDataFromDispatch " << std::endl;
                    return ANALYSIS_ERROR;
                }

                if ( !constructProtobufMessage( DATA_RESPONSE, realData, dt ) )
                {
                    std::cout << "constructProtobufMessage 错误" << std::endl;
                    return ANALYSIS_ERROR;
                }
                return ANALYSIS_SUCCESS;
            }
            else
            {
                std::cerr << "不正确的DataType" << std::endl;
                return ANALYSIS_ERROR;
            }
        }
        else if ( mt == DATA_SUBMISSION )
        {

            //执行数据提交的方法
            //首先需要获取到数据
            std::string data = msgInfo_.realData;
            std::cout << "651:" << data << std::endl;
            BlockOpMsg blockData;
            blockData.fd = fd_;
            blockData.daop = DATAUPLOAD;
            size_t dataLen = data.size();
            blockData.data_len = dataLen;
            memcpy( blockData.data, data.c_str(), dataLen );
            std::string real( blockData.data, blockData.data_len );

            std::cout << "658:" << real << std::endl;
            //数据的格式为：["ID","DJI","master","Status"],[···],[···],······· ;
            //发送数据到消息分发器
            bool flag = msgDp_->dp_send( fd_, blockData, 10 );
            if ( !flag )
            {
                std::cerr << "数据通过消息分发器发送到区块链程序失败" << std::endl;
                return ANALYSIS_ERROR;
            }

            //从消息分发器中接收数据
            std::vector< BlockOpMsg > msgVector = msgDp_->dp_receive( fd_ );
            // std::cout << "msgVector的大小：" << msgVector.size() << std::endl;
            std::string realData;
            if ( !msgVector.empty() )
            {
                const BlockOpMsg &receiveMsg = msgVector.back();
                realData.assign( receiveMsg.data, receiveMsg.data_len );
                msgVector.pop_back();
                // std::cout << realData << std::endl;
                if ( msgVector.size() > 1 )
                {
                    msgVector.clear();
                }
            }
            else
            {
                std::cerr << "msgVector为空" << std::endl;
                return ANALYSIS_ERROR;
            }
            if ( !constructProtobufMessage( DATA_ACKNOWLEDGEMENT, realData, NOTBOTH ) )
            {
                std::cout << "constructProtobufMessage 错误" << std::endl;
                return ANALYSIS_ERROR;
            }
            return ANALYSIS_SUCCESS;
        }

        else if ( mt == DATA_ACKNOWLEDGEMENT )
        {
            std::cout << "收到了DATA_ACKNOWLEDGEMENT" << std::endl;
            return ANALYSIS_SUCCESS;
        }
        else if ( mt == CONTROL_MESSAGE )
        {
            return ANALYSIS_SUCCESS;
        }
        else if ( mt == STATUS_QUERY )
        {
            return ANALYSIS_SUCCESS;
        }
        else
        {
            std::cout << "ANALYSIS_ERROR" << std::endl;
            return ANALYSIS_ERROR;
        }
        // return ANALYSIS_SUCCESS;
    }

    std::vector< DroneData > DdapData::parseDroneData( std::string data )
    {
        std::vector< DroneData > drones;
        size_t start = 0;

        while ( start < data.size() )
        {
            DroneData drone;
            std::string fields[ 4 ];
            bool valid = true;

            for ( int i = 0; i < 4; ++i )
            {
                size_t pos = data.find( "\"", start );
                if ( pos == std::string::npos )
                {
                    std::cout << "数据格式不正确" << std::endl;
                    valid = false;
                    break;
                }
                start = pos + 1;
                pos = data.find( "\"", start );
                if ( pos == std::string::npos )
                {
                    std::cout << "数据格式不正确" << std::endl;
                    valid = false;
                    break;
                }
                fields[ i ] = data.substr( start, pos - start );
                start = pos + 1;
            }

            if ( !valid )
                break;

            drone.id = fields[ 0 ];
            drone.deviceType = fields[ 1 ];
            drone.model = fields[ 2 ];
            drone.status = fields[ 3 ];
            drones.push_back( drone );

            size_t next = data.find( ";", start );
            if ( next == std::string::npos )
                break;
            start = next + 1;
        }

        return drones;
    }

    bool DdapData::constructProtobufMessage( MessageType mt, std::string &sendData, DataType dt )
    {
        //构造FullMessage消息
        msgInfo_.realData = sendData;
        msgInfo_.realDataLength = sendData.size();
        //然后就需要发送DATA_RESPONSE消息
        setMessageInfo( msgInfo_, mt );
        msgInfo_.dataType = dt;
        //然后就需要构造FullMessage消息了
        std::string fullMsgStr = constructMessage( fullMsg_, msgInfo_ );

        //然后是将这个消息进行加密
        // 1、设置IV
        symm_.setIv();

        int plainTextLen = fullMsgStr.size();
        unsigned char plainText[ plainTextLen ];
        memcpy( plainText, fullMsgStr.c_str(), plainTextLen );

        unsigned char cipherText[ 4096 ];
        int cipherTextLen = 0;
        //然后进行加密
        bool encryptRet = symm_.aes_Encryption( plainText, plainTextLen, cipherText, &cipherTextLen );
        if ( !encryptRet )
        {
            std::cout << "加密数据失败" << std::endl;
            return false;
        }

        std::string encryFullMsgStr( reinterpret_cast< const char * >( cipherText ), cipherTextLen );
        unsigned char *iv_c = symm_.getIv();

        std::string ivStr( reinterpret_cast< const char * >( iv_c ), 16 );

        //这是构造EncrptyMessage的

        encryptMsg_.set_encryptedfullmessagestring( encryFullMsgStr );
        encryptMsg_.set_iv( ivStr );

        //将encryptMsg_进行序列化
        std::string encryptMsgStr;
        if ( !encryptMsg_.SerializePartialToString( &encryptMsgStr ) )
        {
            std::cout << "encryptMsg_序列化失败" << std::endl;
            return false;
        }

        // if ( encryptMsg_.ParseFromString( encryptMsgStr ) )
        // {
        //     std::cout << "反序列化成功" << std::endl;
        // }

        //计算hmac
        size_t data_len = encryptMsgStr.size();
        unsigned char data[ data_len ];
        memcpy( data, encryptMsgStr.c_str(), data_len );

        unsigned char *hmac_value = NULL;
        size_t hmac_value_len = 0;
        if ( !generateHmac( data, data_len, symmetricKey_, 32, &hmac_value, &hmac_value_len ) )
        {
            std::cout << "计算Hmac失败" << std::endl;
            return false;
        }

        std::string hmacValueStr( reinterpret_cast< const char * >( hmac_value ), hmac_value_len );

        needHmacMsg_.set_encrptymessagestring( encryptMsgStr );
        needHmacMsg_.set_hmacstring( hmacValueStr );

        //序列化
        std::string needHmacMsgStr;
        if ( !needHmacMsg_.SerializePartialToString( &needHmacMsgStr ) )
        {
            std::cout << "needHmacMsg_序列化失败" << std::endl;
            return false;
        }

        // needHmacMsg_.ParseFromString( needHmacMsgStr );
        // std::string s1 = needHmacMsg_.encrptymessagestring();

        //序列化完成了，然后就是添加到发送缓冲区中。
        outBuffer_ += needHmacMsgStr;
        OPENSSL_free( hmac_value );
        return true;
    }

    bool DdapData::getBlockIllegalData( std::string &data )
    {
        int pipe_parent_to_child[ 2 ];
        int pipe_child_to_parent[ 2 ];
        if ( pipe( pipe_parent_to_child ) == -1 || pipe( pipe_child_to_parent ) == -1 )
        {
            perror( "pipe" );
            return false;
        }
        //创建子进程
        pid_t pid = fork();
        if ( pid == -1 )
        {
            perror( "fork" );
            return false;
        }

        if ( pid == 0 )
        {  //子进程

            //需要关闭父写端   0是读端，1是写端
            //关闭子读端
            close( pipe_parent_to_child[ 1 ] );
            close( pipe_child_to_parent[ 0 ] );

            //重定向
            dup2( pipe_parent_to_child[ 0 ], STDIN_FILENO );
            close( pipe_parent_to_child[ 0 ] );

            dup2( pipe_child_to_parent[ 1 ], STDOUT_FILENO );
            close( pipe_child_to_parent[ 1 ] );

            //执行block程序
            execl( "./BlockChainTest", "BlockChainTest", "-QS", "DroneOperator", "illegal", NULL );
            perror( "execl: BlockChainTest" );
            exit( EXIT_FAILURE );
        }
        else
        {
            //关闭子读端
            close( pipe_parent_to_child[ 0 ] );
            close( pipe_child_to_parent[ 1 ] );

            //向子进程发送数据，请求消息没有数据
            close( pipe_parent_to_child[ 1 ] );

            char buffer[ 4096 ];
            int n = read( pipe_child_to_parent[ 0 ], buffer, sizeof( buffer ) - 1 );
            if ( n <= 0 )
            {
                return false;
            }

            int status;
            wait( &status );
            if ( WIFEXITED( status ) )
            {
                data.append( buffer );
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    bool DdapData::getBlockLegitimateData( std::string &data )
    {
        int pipe_parent_to_child[ 2 ];
        int pipe_child_to_parent[ 2 ];
        if ( pipe( pipe_parent_to_child ) == -1 || pipe( pipe_child_to_parent ) == -1 )
        {
            perror( "pipe" );
            return false;
        }
        //创建子进程
        pid_t pid = fork();
        if ( pid == -1 )
        {
            perror( "fork" );
            return false;
        }

        if ( pid == 0 )
        {  //子进程

            //需要关闭父写端   0是读端，1是写端
            //关闭子读端
            close( pipe_parent_to_child[ 1 ] );
            close( pipe_child_to_parent[ 0 ] );

            //重定向
            dup2( pipe_parent_to_child[ 0 ], STDIN_FILENO );
            close( pipe_parent_to_child[ 0 ] );

            dup2( pipe_child_to_parent[ 1 ], STDOUT_FILENO );
            close( pipe_child_to_parent[ 1 ] );

            //执行block程序
            execl( "./BlockChainTest", "BlockChainTest", "-QS", "DroneOperator", "legitimate", NULL );
            perror( "execl: BlockChainTest" );
            exit( EXIT_FAILURE );
        }
        else
        {
            //关闭子读端
            close( pipe_parent_to_child[ 0 ] );
            close( pipe_child_to_parent[ 1 ] );

            close( pipe_parent_to_child[ 1 ] );

            char buffer[ 4096 ];
            int n = read( pipe_child_to_parent[ 0 ], buffer, sizeof( buffer ) - 1 );
            if ( n <= 0 )
            {
                return false;
            }

            int status;
            wait( &status );
            if ( WIFEXITED( status ) )
            {
                data.append( buffer );
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    bool DdapData::publishDroneInfoToBlock( std::string data )
    {

        int pipe_parent_to_child[ 2 ];
        if ( pipe( pipe_parent_to_child ) == -1 )
        {
            perror( "pipe" );
            return false;
        }

        //
        pid_t pid = fork();
        if ( pid == -1 )
        {
            perror( "fork" );
            return false;
        }

        if ( pid == 0 )
        {
            //关闭管道写端
            close( pipe_parent_to_child[ 1 ] );
            //从管道读端读数据
            unsigned char buffer[ 4096 ];

            size_t n = read( pipe_parent_to_child[ 0 ], buffer, sizeof( buffer ) - 1 );
            if ( n <= 0 )
            {
                perror( "read error" );
                exit( EXIT_FAILURE );
            }
            //转换为字符串
            std::string data( reinterpret_cast< const char * >( buffer ), n );
            //首先需要提取数据
            //数据的结构 0x12345676,DJI,master,legitimate
            //先只处理只有一行数据的情况

            std::stringstream ss( data );
            std::string tmp;
            std::vector< std::string > DronInfoVector;
            while ( std::getline( ss, tmp, ',' ) )
            {
                if ( tmp.empty() )
                {
                    return false;
                }
                DronInfoVector.push_back( tmp );
                tmp.clear();
            }
            const char *droneId = DronInfoVector[ 0 ].c_str();
            const char *droneDT = DronInfoVector[ 1 ].c_str();
            const char *droneModel = DronInfoVector[ 2 ].c_str();
            const char *droneStatus = DronInfoVector[ 3 ].c_str();
            // std::cout << "唯一性检查失败" << std::endl;

            execl( "./BlockChainTest",
                   "BlockChainTest",
                   "-U",
                   "DroneOperator",
                   droneId,
                   droneDT,
                   droneModel,
                   droneStatus,
                   NULL );

            perror( "execl: BlockChainTest" );
            exit( EXIT_FAILURE );
        }
        else
        {
            //写数据到管道中
            size_t n = write( pipe_parent_to_child[ 1 ], data.c_str(), data.size() );
            if ( n <= 0 )
            {
                return false;
            }

            close( pipe_parent_to_child[ 1 ] );
            int status;
            auto start = std::chrono::high_resolution_clock::now();

            wait( &status );
            auto stop = std::chrono::high_resolution_clock::now();
            std::chrono::duration< double, std::milli > elapsed = stop - start;
            std::cout << "Wait Time taken: " << elapsed.count() << " ms\n";
            if ( WIFEXITED( status ) )
            {

                // std::cout << "1016" << std::endl;
                if ( WEXITSTATUS( status ) == EXIT_SUCCESS )
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
    }

    std::string DdapData::getDataFromDispatch( std::string &string )
    {
        BlockOpMsg blockData;
        blockData.fd = fd_;
        blockData.daop = DATADOWNLOAD;
        size_t dsLen = string.size();
        blockData.data_len = dsLen;
        std::string realData;
        memcpy( blockData.data, string.c_str(), dsLen );

        msgDp_->dp_send( fd_, blockData, 10 );

        //接收数据
        std::vector< BlockOpMsg > msgVector = msgDp_->dp_receive( fd_ );
        // std::cout << "msgVector的大小：" << msgVector.size() << std::endl;
        if ( !msgVector.empty() )
        {
            const BlockOpMsg &receiveMsg = msgVector.back();
            realData.assign( receiveMsg.data, receiveMsg.data_len );
            std::cout << realData << std::endl;
            msgVector.pop_back();
            std::cout << msgVector.size() << std::endl;
            if ( msgVector.size() > 1 )
            {
                msgVector.clear();
            }
        }
        return realData;
    }
}  // namespace droneswarm